package com.woniu51.k15demo.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.woniu51.k15demo.entity.Manager;
import com.woniu51.k15demo.entity.Permission;
import com.woniu51.k15demo.entity.Role;
import com.woniu51.k15demo.exception.AppException;
import com.woniu51.k15demo.mapper.*;
import com.woniu51.k15demo.service.ManagerService;
import com.woniu51.k15demo.utils.JwtUtil;
import com.woniu51.k15demo.vo.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author 杨光
 * @date 2022年02月14日 17:50
 */
@Service
public class ManagerServiceImpl implements ManagerService {
    @Autowired
    ManagerMapper managerMapper;
    @Autowired
    PermissionMapper permissionMapper;

    @Autowired
    RoleMapper roleMapper;

    @Autowired
    RolePermissionMapper rolePermissionMapper;

    @Autowired
    ManagerRoleMapper managerRoleMapper;

    @Autowired
    RedisTemplate redisTemplate;



    @Override
    public String doLogin(LoginDto loginDto) {
        Manager manager = managerMapper.selectByUserNameAndPassword(loginDto);
        //如果manager == null
        if(manager==null){
            throw new AppException(100100,"用户或密码失败");
        }

        //把用户的接口权限查询出来，缓存在redis
        Set<String> urlPermisionList = permissionMapper.queryInterfacePermissionByManagerId(manager.getId());
        for (String url : urlPermisionList) {
            redisTemplate.opsForSet().add("urlPermissions_"+manager.getId(),url);
        }


        //用户登录成功了，生成jwt
        String jwt = JwtUtil.generateJWT(manager);
        return jwt;

    }

    @Override
    public PageInfo<Permission> queryPermissionWithPage(Integer pageNum, Integer pageSize, String name) {
        PageHelper.startPage(pageNum,pageSize);
        List<Permission> list= permissionMapper.selectPermissionByNameLike(name);
        return new PageInfo<>(list);
    }

    @Override
    public List<Permission> queryFirstLevelPermission() {
        List<Permission> list= permissionMapper.queryFirstLevelPermission();
        return list;


    }

    @Override
    public void addPermission(PermissionDto permissionDto) {
        Permission permission = new Permission();

        if(permissionDto.getParentId().compareTo(0L)==0){
            permissionDto.setParentId(-1L);
            permissionDto.setUrl("");
        }
        //两个对象里面相同属性会自动复制
        BeanUtils.copyProperties(permissionDto,permission);
        permission.setUrlType("1");
        permission.setInsertTime(new Date());
        permission.setUpdateTime(new Date());
        permissionMapper.insert(permission);
    }

    @Override
    public PageInfo<Role> queryRoleWithPage(Integer pageNum, Integer pageSize, String name) {
        PageHelper.startPage(pageNum,pageSize);
        List<Role> list= roleMapper.selectRoleByNameLike(name);

        return new PageInfo<>(list);
    }

    @Override
    public void addRole(RoleDto roleDto) {
        Role role = new Role();
        BeanUtils.copyProperties(roleDto,role);
        role.setInsertTime(new Date());
        role.setUpdateTime(new Date());
        roleMapper.insert(role);

    }


    @Override
    public Role getRoleById(Long id) {
        return roleMapper.selectByPrimaryKey(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)//@transactional注解默认捕获RuntimeException，现在指定捕获所有类型异常
    public void editRole(RoleDto roleDto) {
        Role role = new Role();

//        BeanUtils.copyProperties(roleDto,role);
        role.setUpdateTime(new Date());
        role.setName(roleDto.getName());
        role.setId(roleDto.getId());
        roleMapper.updateByPrimaryKey(role);

        //根据roleId删除t_role_url_permission中的角色和权限的关联数据
        rolePermissionMapper.deleteByRoleId(roleDto.getId());
        //批量插入角色和权限的对应数据
        /**
         *
         * 1.把permString字符串转成数组
         * 2.通过流的形式遍历这个字符串数组，并且把每一个元素转成了长整型
         * 3.把这些长整型的数据放入了一个List中
         */

        List<Long> permIdList = Arrays.stream(roleDto.getPermString().split(","))
                .map(s -> {
                    return Long.valueOf(s);
                }).collect(Collectors.toList());
        rolePermissionMapper.batchInsert(roleDto.getId(),permIdList);

    }

    @Override
    public List<PermissionTree> queryPermissionTreeLevel1() {

       return  permissionMapper.queryPermissionTreeLevel1();
    }

    @Override
    public RoleVo getRoleAndPermissionsById(Long id) {


        return  roleMapper.getRoleAndPermissionsById(id);

    }
    @Transactional(rollbackFor = Exception.class)//@transactional注解默认捕获RuntimeException，现在指定捕获所有类型异常
    @Override
    public void deleteByRoleId(Long id) {
        //根据roleId删除角色和权限的关联表数据
        rolePermissionMapper.deleteByRoleId(id);
        //根据roleId删除用户和角色的关联数据
        managerRoleMapper.deleteByRoleId(id);
        //根据id删除角色
        roleMapper.deleteByPrimaryKey(id);
    }

    @Override
    public PageInfo<ManagerVo> queryManagerWithPage(Integer pageNum, Integer pageSize, String userName) {
        PageHelper.startPage(pageNum,pageSize);
        List<ManagerVo> list  = managerMapper.selectManagerByUserNameLike(userName);
        return new PageInfo<>(list);
    }

    @Override
    public List<Role> queryAllRoles() {

        return roleMapper.selectAll();

    }

    @Override
    public Manager queryManagerById(Long id) {

        return managerMapper.selectByPrimaryKey(id);

    }

    @Override
    public List<Long> queryRoleIdListByManagerId(Long id) {

        List<Long> list = managerRoleMapper.selectRoleIdListByManagerId(id);

        return list;
    }

    @Transactional(rollbackFor = Exception.class)//@transactional注解默认捕获RuntimeException，现在指定捕获所有类型异常
    @Override
    public void editUser(ManagerDto managerDto) {
        Manager manager = new Manager();

        //复制对象
        BeanUtils.copyProperties(managerDto,manager);

        //更新用户信息
        managerMapper.updateByPrimaryKey(manager);

        //删除用户和角色的关联记录
        managerRoleMapper.deleteByManagerId(managerDto.getId());

        //插入用户和角色的关联记录
        managerRoleMapper.batchInsert(managerDto.getId(),managerDto.getRoleIds());

    }

    @Override
    public List<PermissionTree> queryPermissionsByManagerId(Long userId) {

        return permissionMapper.queryPermissionsByManagerId(userId);

    }


}
